package com.heima.user.service.impl;

import com.heima.common.constants.user.UserRelationConstants;
import com.heima.common.exception.CustException;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.threadlocal.AppThreadLocalUtils;
import com.heima.model.user.dtos.UserRelationDTO;
import com.heima.model.user.pojos.ApUser;
import com.heima.user.service.ApUserRelationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

/**
 * @authar by xiecong
 * @Date 2022/3/12
 * @Description
 */
@Service
@Slf4j
public class ApUserRelationServiceImpl implements ApUserRelationService {

    @Autowired
    StringRedisTemplate redisTemplate;

    /**
     * 用户关注/取消关注
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult follow(UserRelationDTO dto) {
        // 1. 校验参数    authorApUserId   必须登录   operation: 0关注  1取消关注
        if (dto.getAuthorApUserId() == null) {
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST, "作者对应的id不存在");
        }
        ApUser user = AppThreadLocalUtils.getUser();
        if (user == null) {
            CustException.cust(AppHttpCodeEnum.NEED_LOGIN);
        }
        Short operation = dto.getOperation();
        if (operation == null || operation.intValue() != 0 || operation.intValue() != 1) {
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID, "操作方式错误");
        }


        Integer userLoginId = user.getId();  //用户登陆id
        Integer followId = dto.getAuthorApUserId();  //登陆用户关注的作者id
        ZSetOperations<String, String> zsetOperation = redisTemplate.opsForZSet();
        // 2. 如果是关注请求
        if (operation.intValue() == 0) {
            //    如果是关注请求，查看是否已经关注: zscore
            //    参数1： key   参数2: 要查询集合元素 参数3: score时间
            Double score = zsetOperation.score(UserRelationConstants.FOLLOW_LIST + userLoginId, String.valueOf(followId));
            // 判断自己不可以关注自己
            if (userLoginId.equals(followId)) {
                CustException.cust(AppHttpCodeEnum.DATA_NOT_ALLOW, "自己不能关注自己");
            }
            if (score != null) {
                // 不为空说明已经关注过
                CustException.cust(AppHttpCodeEnum.DATA_EXIST, "已经关注过");
            } else {
                // 为空则添加关注:zadd
                //添加数据，follow : 用户userLoginId  作者followId
                zsetOperation.add(UserRelationConstants.FOLLOW_LIST + userLoginId
                                    , String.valueOf(followId)
                                    , System.currentTimeMillis());
                //添加数据，follow : 作者followId  用户userLoginId
                zsetOperation.add(UserRelationConstants.FANS_LIST + followId
                                    , String.valueOf(userLoginId)
                                    , System.currentTimeMillis());
            }
        } else {
            // 3.  如果是取消关注请求:zrem
            //删除数据，follow : 用户userLoginId  作者followId
            zsetOperation.remove(UserRelationConstants.FOLLOW_LIST + userLoginId
                                    ,String.valueOf(followId));
            //删除数据，follow : 作者followId  用户userLoginId
            zsetOperation.remove(UserRelationConstants.FANS_LIST + followId
                                    ,String.valueOf(userLoginId));
        }
        return ResponseResult.okResult();
    }
}
